package com.rf.sys.control;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.rf.sys.frm.BaseController;
import com.rf.sys.model.Dictionary;
import com.rf.sys.model.User;
import com.rf.sys.model.UserLoginLog;
import com.rf.sys.service.DictionaryService;
import com.rf.sys.service.ResourcesService;
import com.rf.sys.service.RoleService;
import com.rf.sys.service.UserLoginLogService;
import com.rf.sys.service.UserService;
import com.rf.sys.utils.CommonUtils;
import com.rf.sys.utils.JsonUtils;
import com.rf.sys.utils.MD5Util;
import com.rf.sys.utils.TreeObject;
import com.rf.sys.utils.TreeUtil;

@Controller
@RequestMapping("/")
public class AdminController extends BaseController{

	private static Logger log = LoggerFactory.getLogger(AdminController.class);
	private static final long serialVersionUID = -120160118162025167L;
	
	@Resource
	private UserService userService;
	@Resource
	private UserLoginLogService userLoginLogService;
	@Resource
	private ResourcesService resourcesService;
	@Resource
	private RoleService roleService;
	@Resource
	private DictionaryService dictionaryService;
	
	/**
	 * 登陆
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "login")
	public void login (HttpServletRequest request, HttpServletResponse response) throws Exception{
		JSONObject returnObj = new JSONObject();
		MD5Util md5 = new MD5Util();
		String loginName = request.getParameter("loginName");
		String password = request.getParameter("password");
		if (CommonUtils.isEmpty(loginName) || CommonUtils.isEmpty(password)) {
			returnObj.element("message", "isNull");//用户名密码为空
		}
		// 想要得到 SecurityUtils.getSubject()　的对象．．访问地址必须跟shiro的拦截地址内．不然后会报空指针
		Subject subject = SecurityUtils.getSubject();
		// 用户输入的账号和密码,,存到UsernamePasswordToken对象中..然后由shiro内部认证对比,
		// 认证执行者交由ShiroDbRealm中doGetAuthenticationInfo处理
		// 当以上认证成功后会向下执行,认证失败会抛出异常
		UsernamePasswordToken token = new UsernamePasswordToken(loginName, password);
		try {
			//通过Shiro进行用户名密码验证
			subject.login(token);
			
			//将用户登陆信息保存到数据库
			Session session = SecurityUtils.getSubject().getSession();
			UserLoginLog userLoginLog = new UserLoginLog();
			userLoginLog.setUserId((String)session.getAttribute("userSessionId"));
			userLoginLog.setAccountName(loginName);
			userLoginLog.setLoginIp(session.getHost());
			userLoginLogService.addUserLoginLog(userLoginLog);
			//登陆成功
			returnObj.element("message", "success");//成功
		} catch(UnknownAccountException uae){
			token.clear();
			returnObj.element("message", "usernotfound");//用户未找到
		} catch(IncorrectCredentialsException ice){
			token.clear();
			returnObj.element("message", "errorpwd");//密码错误
		}catch (LockedAccountException lae) {
			token.clear();
			returnObj.element("message", "userlock");//用户已经被锁定,不能登录
		} catch (ExcessiveAttemptsException e) {
			token.clear();
			returnObj.element("message", "failuremany");//登录失败次数过多
		} catch (AuthenticationException e) {
			token.clear();
			returnObj.element("message", "usererror");//用户错误
		}
		super.responseJson(request, response, returnObj.toString());
     }
	
	/**
	 * 退出
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("logout")
	public ModelAndView loginout(HttpServletRequest request,HttpServletResponse response) throws Exception {
		ModelAndView modelView = new ModelAndView();
		request.getSession().removeAttribute("systemUser");
		modelView.setViewName("index");//跳转到首页面
		return modelView;
	}
	
	/**
	 * 加载登录后的主页面,初始化用户菜单
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "main")
	public ModelAndView main (HttpServletRequest request, HttpServletResponse response) throws Exception{
		ModelAndView modelAndView = new ModelAndView();
		Session session = SecurityUtils.getSubject().getSession();
		User user = (User)session.getAttribute("userSession");
		if(user != null){
			List<Map<String, Object>> rList = resourcesService.getResourcesByUserId(user.getId());
			List<TreeObject> list = new ArrayList<TreeObject>();
			for (Map<String, Object> r : rList) {
				TreeObject ts = new TreeObject();
				CommonUtils.flushObject(ts, r);
				list.add(ts);
			}
			TreeUtil treeUtil = new TreeUtil();
			List<TreeObject> resList = treeUtil.getChildTreeObjects(list,"0");
			JSONArray jsonArray = JSONArray.fromObject(resList);
			modelAndView.addObject("resList", "{\"basic\":"+jsonArray.toString()+"}");
			modelAndView.addObject("userName", user.getUserName());
			modelAndView.setViewName("/main");
		}else{
			modelAndView.addObject("error", "登陆超时,请重新登陆!");
			modelAndView.setViewName("/index");
		}
        return modelAndView;
	}
	
	/**
	 * 获取数据字典
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("getDicText")
	public void getDicText(HttpServletRequest request,HttpServletResponse response) throws Exception {
		String classCode = request.getParameter("classCode");
		Dictionary dictionary = new Dictionary();
		dictionary.setClassCode(classCode);
		List<Dictionary> list = dictionaryService.getDictionary(dictionary);
		super.responsePrint(request, response, JsonUtils.listToJson(list));
	}
	
}
